﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;

using System.Drawing;
using System.Threading;

using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;

namespace NGE
{
    public class Graph
    {
        public Graph(Game g)
        {
            game = g;

            //PictureBox pb = null;
            //if (game.GameControl is System.Windows.Forms.Form)
            //{
            //    pb = new PictureBox();
            //    pb.Width = game.Option.WindowSize.Width;
            //    pb.Height = game.Option.WindowSize.Height;
            //    pb.Parent = game.GameControl;
            //    game.GameControl.si
            //}
            //else
            {
                //game.GameControl.Width = game.Option.WindowSize.Width;
                //game.GameControl.Height = game.Option.WindowSize.Height;
            }
            game.GameControl.ClientSize = game.Option.WindowSize;

            draw3d = true;
            pps = new Microsoft.DirectX.Direct3D.PresentParameters();
            pps.SwapEffect = Microsoft.DirectX.Direct3D.SwapEffect.Discard;
            pps.Windowed = true;
            pps.EnableAutoDepthStencil = false;


            //if (g.Option.IsFixSize)
            {
                pps.BackBufferWidth = game.GameControl.ClientSize.Width;
                pps.BackBufferHeight = game.GameControl.ClientSize.Height;
            }
            pps.BackBufferCount = 1;
            pps.BackBufferFormat = Format.A8R8G8B8;
            pps.PresentationInterval = PresentInterval.One;

            d3ddev = new Microsoft.DirectX.Direct3D.Device(0, Microsoft.DirectX.Direct3D.DeviceType.Hardware,  game.GameControl, Microsoft.DirectX.Direct3D.CreateFlags.SoftwareVertexProcessing, pps);

            d3ddev.DeviceResizing += new System.ComponentModel.CancelEventHandler(onD3DDevDeviceResizing);
            d3ddev.DeviceReset += new EventHandler(onD3DDevDeviceReset);
            d3ddev.DeviceLost += new EventHandler(onD3DDevDeviceLost);

            //vb = new VertexBuffer(typeof(CustomVertex.PositionColoredTextured), 6, d3ddev, Usage.Dynamic|Usage.WriteOnly, CustomVertex.PositionColoredTextured.Format, Pool.Default);
            //d3ddev.SetStreamSource(0, vb, 0);

            //Surface = new Texture(d3ddev, game.Options.WindowSizePixel.Width, game.Options.WindowSizePixel.Height, 0, Usage.None, Format.A8R8G8B8, Pool.Managed);
            //Pen = Surface.GetSurfaceLevel(0).GetGraphics();

            //Pen.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half;
            //Pen.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;

            initD3DDev();

            //sprite = new Microsoft.DirectX.Direct3D.Sprite(d3ddev);
            //if (draw3dtext)
            {
                
            }
            //else
            //{
            //    font = new System.Drawing.Font(game.Option.FontName, game.Option.FontSize * ((float)game.Option.Zoom - 0.5f), game.Option.FontStyle, GraphicsUnit.Pixel);
            //}
            //d3dfont = new Microsoft.DirectX.Direct3D.Font(d3ddev, font);

            surface = new Bitmap(game.Option.WindowSize.Width, game.Option.WindowSize.Height);
            CPUGraph = Graphics.FromImage(surface);

            //Thread animationThread = new Thread(animationHeartbeat);
            //animationThread.IsBackground = true;
            //animationThread.Start();
        }

        Game game;

        bool draw3d;
        //Microsoft.DirectX.Direct3D.Font d3dfont;
        PresentParameters pps;
        Device d3ddev;
        CustomVertex.PositionColoredTextured[] Vertexs = new CustomVertex.PositionColoredTextured[6];
        //VertexBuffer vb;
        CustomVertex.PositionColored[] Vertexs2 = new CustomVertex.PositionColored[8];

        Size Resolution
        {
            get
            {
                return new Size(d3ddev.PresentationParameters.BackBufferWidth, d3ddev.PresentationParameters.BackBufferHeight);
            }
        }

        Bitmap surface;
        Graphics CPUGraph;
        //Microsoft.DirectX.Direct3D.Sprite sprite;

        bool isNeedCPUClear;

        bool isNeedCPUDraw;

        void initD3DDev()
        {
            initViewport(game.Option.Zoom);
            //d3ddev.RenderState.CullMode = Cull.None;
            d3ddev.RenderState.AlphaBlendEnable = true;
            d3ddev.RenderState.SourceBlend = Microsoft.DirectX.Direct3D.Blend.SourceAlpha;
            d3ddev.RenderState.DestinationBlend = Microsoft.DirectX.Direct3D.Blend.InvSourceAlpha;
            d3ddev.RenderState.Lighting = false;
            d3ddev.TextureState[0].AlphaOperation = TextureOperation.Modulate;
        }

        void initViewport(double zoomx)
        {
            Vector3 location = new Vector3();
            location.Z = -(float)((double)Resolution.Height / (2.0 * zoomx) / Math.Tan(22.5f * Math.PI / 180.0));

            d3ddev.Transform.Projection = Matrix.PerspectiveFovLH((float)Math.PI / 4, (float)Resolution.Width / (float)Resolution.Height, -100, 100);
            d3ddev.Transform.View = Matrix.LookAtLH(location, new Vector3(), new Vector3(0, 1, 0));
        }

        public void Zoom(double x)
        {
            game.Option.Zoom = Math.Pow(2, x);
            initViewport(game.Option.Zoom);
        }

        void onD3DDevDeviceResizing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            e.Cancel = true;
        }

        void onD3DDevDeviceLost(object sender, EventArgs e)
        {
            //throw new NotImplementedException();
            //if (Vertexs != null)
            //{
            //    Vertexs = null;
            //}
        }

        void onD3DDevDeviceReset(object sender, EventArgs e)
        {
            initD3DDev();
        }

        void drawImageGPU(Texture texture, Size textureSize, bool isFlip, Color filterColor, Rectangle srcRect, Size size, Vector3 v3)
        {
            if (draw3d)
            {
                v3.X -= Resolution.Width / 2 / (float)game.Option.Zoom;
                v3.Y -= Resolution.Height / 2 / (float)game.Option.Zoom;
                v3.Y = -v3.Y;
                
                float x = 0;
                float y = 0;
                float z = 0;

                float fu = 0f;
                float fv = 0f;
                float tu = 1f;
                float tv = 1f;

                int color_int = filterColor.ToArgb();

                int width = size.Width;
                int height = size.Height;

                //textureSize.Width = texture.GetSurfaceLevel(0).Description.Width;
                //textureSize.Height = texture.GetSurfaceLevel(0).Description.Height;
                fu = (0.5f + (float)srcRect.Left) / (float)textureSize.Width;
                fv = (0.5f + (float)srcRect.Top) / (float)textureSize.Height;
                tu = (0.0f + (float)srcRect.Right) / (float)textureSize.Width;
                tv = (0.0f + (float)srcRect.Bottom) / (float)textureSize.Height;

                if (isFlip)
                {
                    fu = -fu;
                    tu = -tu;
                }


                //Vertexs[0] = new CustomVertex.PositionColoredTextured(x, y, z, color_int, fu, fv);
                //Vertexs[1] = new CustomVertex.PositionColoredTextured(x + width, y - height, z, color_int, tu, tv);
                //Vertexs[2] = new CustomVertex.PositionColoredTextured(x, y - height, z, color_int, fu, tv);

                //Vertexs[3] = new CustomVertex.PositionColoredTextured(x, y, z, color_int, fu, fv);
                //Vertexs[4] = new CustomVertex.PositionColoredTextured(x + width, y, z, color_int, tu, fv);
                //Vertexs[5] = new CustomVertex.PositionColoredTextured(x + width, y - height, z, color_int, tu, tv);

                Vertexs[0].X = x;
                Vertexs[0].Y = y;
                Vertexs[0].Z = z;
                Vertexs[0].Tu = fu;
                Vertexs[0].Tv = fv;
                Vertexs[0].Color = color_int;

                Vertexs[1].X = x + width;
                Vertexs[1].Y = y - height;
                Vertexs[1].Z = z;
                Vertexs[1].Tu = tu;
                Vertexs[1].Tv = tv;
                Vertexs[1].Color = color_int;

                Vertexs[2].X = x;
                Vertexs[2].Y = y - height;
                Vertexs[2].Z = z;
                Vertexs[2].Tu = fu;
                Vertexs[2].Tv = tv;
                Vertexs[2].Color = color_int;

                Vertexs[3].X = x;
                Vertexs[3].Y = y;
                Vertexs[3].Z = z;
                Vertexs[3].Tu = fu;
                Vertexs[3].Tv = fv;
                Vertexs[3].Color = color_int;

                Vertexs[4].X = x + width;
                Vertexs[4].Y = y;
                Vertexs[4].Z = z;
                Vertexs[4].Tu = tu;
                Vertexs[4].Tv = fv;
                Vertexs[4].Color = color_int;

                Vertexs[5].X = x + width;
                Vertexs[5].Y = y - height;
                Vertexs[5].Z = z;
                Vertexs[5].Tu = tu;
                Vertexs[5].Tv = tv;
                Vertexs[5].Color = color_int;

                d3ddev.VertexFormat = CustomVertex.PositionColoredTextured.Format;
                d3ddev.Transform.World = Matrix.Translation(v3);
                d3ddev.SetTexture(0, texture);
                d3ddev.DrawUserPrimitives(PrimitiveType.TriangleList, 2, Vertexs);

                //vb.SetData(Vertexs, 0, LockFlags.None);
                //d3ddev.DrawPrimitives(PrimitiveType.TriangleList, 0, 2);
            }
            else
            {
                //sprite.Begin(SpriteFlags.AlphaBlend);
                //sprite.Draw(texture, srcRect, new Vector3(), v3, filterColor);
                //Rectangle drect = new Rectangle();
                //drect = srcRect;
                ////drect.Width *= 2;
                ////drect.Height *= 2;
                //sprite.Draw2D(texture, srcRect, drect, Util.Vector32Point(v3), filterColor);
                //sprite.End();
            }
        }

        void drawRectGPU(Size size, Color filterColor, bool fill, Vector3 v3)
        {
            if (draw3d)
            {
                v3.X -= Resolution.Width / 2 / (float)game.Option.Zoom;
                v3.Y -= Resolution.Height / 2 / (float)game.Option.Zoom;
                v3.Y = -v3.Y;

                float x = 0;
                float y = 0;
                float z = 0;

                int color_int = filterColor.ToArgb();

                int width = size.Width;
                int height = size.Height;

                d3ddev.VertexFormat = CustomVertex.PositionColored.Format;
                d3ddev.Transform.World = Matrix.Translation(v3);
                d3ddev.SetTexture(0, null);

                if (fill)
                {
                    Vertexs2[0].X = x;
                    Vertexs2[0].Y = y;
                    Vertexs2[0].Z = z;
                    Vertexs2[0].Color = color_int;

                    Vertexs2[1].X = x + width;
                    Vertexs2[1].Y = y - height;
                    Vertexs2[1].Z = z;
                    Vertexs2[1].Color = color_int;

                    Vertexs2[2].X = x;
                    Vertexs2[2].Y = y - height;
                    Vertexs2[2].Z = z;
                    Vertexs2[2].Color = color_int;

                    Vertexs2[3].X = x;
                    Vertexs2[3].Y = y;
                    Vertexs2[3].Z = z;
                    Vertexs2[3].Color = color_int;

                    Vertexs2[4].X = x + width;
                    Vertexs2[4].Y = y;
                    Vertexs2[4].Z = z;
                    Vertexs2[4].Color = color_int;

                    Vertexs2[5].X = x + width;
                    Vertexs2[5].Y = y - height;
                    Vertexs2[5].Z = z;
                    Vertexs2[5].Color = color_int;

                    d3ddev.DrawUserPrimitives(PrimitiveType.TriangleList, 2, Vertexs2);
                }
                else
                {
                    Vertexs2[0].X = x;
                    Vertexs2[0].Y = y;
                    Vertexs2[0].Z = z;
                    Vertexs2[0].Color = color_int;

                    Vertexs2[1].X = x + width;
                    Vertexs2[1].Y = y;
                    Vertexs2[1].Z = z;
                    Vertexs2[1].Color = color_int;

                    Vertexs2[2].X = x + width;
                    Vertexs2[2].Y = y ;
                    Vertexs2[2].Z = z;
                    Vertexs2[2].Color = color_int;

                    Vertexs2[3].X = x + width;
                    Vertexs2[3].Y = y - height;
                    Vertexs2[3].Z = z;
                    Vertexs2[3].Color = color_int;

                    Vertexs2[4].X = x + width;
                    Vertexs2[4].Y = y - height;
                    Vertexs2[4].Z = z;
                    Vertexs2[4].Color = color_int;

                    Vertexs2[5].X = x;
                    Vertexs2[5].Y = y - height;
                    Vertexs2[5].Z = z;
                    Vertexs2[5].Color = color_int; 
                    
                    Vertexs2[6].X = x;
                    Vertexs2[6].Y = y;
                    Vertexs2[6].Z = z;
                    Vertexs2[6].Color = color_int;

                    Vertexs2[7].X = x;
                    Vertexs2[7].Y = y - height;
                    Vertexs2[7].Z = z;
                    Vertexs2[7].Color = color_int;

                    d3ddev.DrawUserPrimitives(PrimitiveType.LineList, 4, Vertexs2);
                }
            }
        }

        void drawTextGPU(string text, Vector3 v3, System.Drawing.Font font, Color color, bool drawbg)
        {
            //if (draw3dtext)

            Size fsize = new Size((int)font.Height, (int)font.Height);
            Size tsize = Util.GetTextSize(text, fsize);
            string[] texts = Util.GetTextLines(text);

            if (tsize.Width > Resolution.Width)
            {
                tsize.Width = Resolution.Width;
            }
            if (tsize.Height > Resolution.Height)
            {
                tsize.Height = Resolution.Height;
            }
            if (tsize.Width == 0)
            {
                return;
            }

            using (Texture texture = new Texture(d3ddev, tsize.Width, tsize.Height, 1, Usage.None, Format.A8R8G8B8, Pool.Managed))
            {
                using (System.Drawing.Graphics g = texture.GetSurfaceLevel(0).GetGraphics())
                {
                    //g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half;
                    //g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                    for (int i = 0; i < texts.Length; i++)
                    {
                        char[] t = texts[i].ToCharArray();
                        for (int j = 0; j < t.Length; j++)
                        {
                            g.DrawString(t[j].ToString(), font, new SolidBrush(color), j * fsize.Width, i * fsize.Height);
                        }
                    }
                }
                if (drawbg)
                {
                    drawRectGPU(tsize, Color.FromArgb(200, 0, 0, 0), true, v3);
                }

                drawImageGPU(texture, tsize, false, Color.White, new Rectangle(new Point(), tsize), tsize, v3);
            }
            //else
            {
                //sprite.Begin(SpriteFlags.AlphaBlend);
                //f = new System.Drawing.Font(f.FontFamily, f.Size, GraphicsUnit.Pixel);
                //if (font != f)
                //{
                //    d3dfont.Dispose();
                //    font.Dispose();
                //    font = f;
                //    d3dfont = new Microsoft.DirectX.Direct3D.Font(d3ddev, font);
                //}
                //Point loc = Util.Vector32Point(v3);
                //loc.X *= (int)game.Option.Zoom;
                //loc.Y *= (int)game.Option.Zoom;
                //Rectangle rect=new Rectangle();
                //rect.Location=loc;
                //d3dfont.DrawText(null, text, rect, DrawTextFormat.NoClip, color);
                //sprite.End();
            }
        }

        void drawImageCPU(Image img, Rectangle srect, Point pos, Size siz)
        {
            CPUGraph.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half;
            //CPUGraph.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
            CPUGraph.DrawImage(img, pos.X, pos.Y, srect, GraphicsUnit.Pixel);
            isNeedCPUDraw = true;
            isNeedCPUClear = true;
        }

        void clearSurf()
        {
            if (isNeedCPUClear)
            {
                //CPUClear();
                CPUGraph.Clear(Color.Transparent);
                isNeedCPUClear = false;
            }
        }

        void drawSurf()
        {
            if (isNeedCPUDraw)
            {
                using (Texture texture = new Texture(d3ddev, game.Option.WindowSize.Width, game.Option.WindowSize.Height, 1, Usage.None, Format.A8R8G8B8, Pool.Managed))
                {
                    using (Graphics g = texture.GetSurfaceLevel(0).GetGraphics())
                    {
                        //g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half;
                        //g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
                        g.DrawImage(surface, new Point());
                    }
                    drawImageGPU(texture, game.Option.WindowSize, false, Color.White, new Rectangle(new Point(), game.Option.WindowSize), game.Option.WindowSize, new Vector3());
                }
                //GPUDrawImage(Devices.Surface, Color.White, new Vector3());
                isNeedCPUDraw = false;
            }
        }

        public bool IsWindowed
        {
            set
            {
                d3ddev.PresentationParameters.Windowed = value;
            }
            get
            {
                return d3ddev.PresentationParameters.Windowed;
            }
        }

        public void FreeVideoMemory()
        {
            d3ddev.EvictManagedResources();
        }

        public void Clear()
        {
            //
            d3ddev.Clear(Microsoft.DirectX.Direct3D.ClearFlags.Target, 0, 1f, 0);
            d3ddev.BeginScene();
            clearSurf();
        }
        public void Present()
        {            
            drawSurf();
            d3ddev.EndScene();
            try
            {
                d3ddev.Present();
            }
            catch { }
        }
        public void Reset()
        {
            game.GameControl.Width = game.Option.WindowSize.Width;
            game.GameControl.Height = game.Option.WindowSize.Height;
            d3ddev.PresentationParameters.BackBufferWidth = game.GameControl.Width;
            d3ddev.PresentationParameters.BackBufferHeight = game.GameControl.Height;
            d3ddev.Reset(d3ddev.PresentationParameters);
        }
        public void Dispoise()
        {
            //d3ddev.Dispose();
        }

        #region fast
        public void DrawText(string text, Color color, Vector3 v3)
        {
            DrawText(text, (color), game.Option.Font, v3);
        }
        public void DrawText(string text, Color color, System.Drawing.Font f, Vector3 v3)
        {
            DrawText(text, color, f, false, v3);
        }
        public void DrawText(string text, Color color, System.Drawing.Font f, bool drawbg, Vector3 v3)
        {
            drawTextGPU(text, v3, f, color, drawbg);
        }
        public void DrawRectangle(Color color, Rectangle rect, bool isfill)
        {
            DrawRectangle(new Pen(color), rect, isfill);
        }
        public void DrawRectangle(Pen pen, Rectangle rect, bool isfill)
        {

            drawRectGPU(rect.Size, pen.Color, isfill, Util.Point2Vector3(rect.Location));
        }
        public void DrawImage(NImage img, Vector3 v3)
        {
            DrawImage(img,v3, false);
        }
        public void DrawImage(NImage img, Color filterColor, Vector3 v3)
        {
            DrawImage(img, filterColor, v3, false);
        }
        public void DrawImage(NImage img, Vector3 v3, bool isflip)
        {
            DrawImage(img, Color.White, v3,isflip);
        }
        public void DrawImage(NImage img, Color filterColor, Vector3 v3, bool isflip)
        {
            DrawImage(img, filterColor, new Rectangle(new Point(), img.Size), v3,isflip);
        }
        public void DrawImage(NImage img, Color filterColor, Rectangle rect, Vector3 v3, bool isflip)
        {
            if (img.MemTexture == null)
            {
                img.Init(d3ddev);
            }
            if (game.Option.DrawMode == DrawMode.GPU)
            {
                drawImageGPU(img.MemTexture, img.Size, isflip, filterColor, rect, rect.Size, v3);
            }
            else if (game.Option.DrawMode == DrawMode.CPU)
            {
                drawImageCPU(img.MemImage, rect, Util.Vector32Point(v3), rect.Size);
            }
        }


        public void DrawAnimation(NAnimation ani, Color filterColor, Vector3 v3, bool isflip, bool loop, double gameTimer)
        {
            DrawAnimation(ani,ani.CurrentFrameIndex, filterColor,v3, isflip,loop, gameTimer);
        }
        public void DrawAnimation(NAnimation ani, int frameIndex, Color filterColor, Vector3 v3, bool isflip, bool loop, double gameTimer)
        {
            DrawAnimation(ani, frameIndex, filterColor, v3, new Rectangle(new Point(), ani[frameIndex].Size), isflip,loop, gameTimer);
        }
        public void DrawAnimation(NAnimation ani, int frameIndex, Color filterColor, Vector3 v3, Rectangle rect, bool isflip, bool loop, double gameTimer)
        {
            ani.Heartbeat(gameTimer, loop);
            v3.Y -= ani.CurrentFrame.Height;
            v3.X -= ani.CurrentFrame.Width / 2;
            DrawImage(ani.CurrentFrame, filterColor, rect, v3, isflip);
        }


        /*
        #region memory for animation
        List<NAnimation> nanis = new List<NAnimation>();

        public void AnimationReset(string regname)
        {
            int i = getAnimationIndex(regname);
            if (i >= 0)
            {
                nanis[i].Pause = false;
                nanis[i].Reset();
            }
        }
        public void AnimationPlay(string regname)
        {
            int i = getAnimationIndex(regname);
            if (i >= 0)
            {
                nanis[i].Pause = false;
            }
        }
        public void AnimationPause(string regname)
        {
            int i = getAnimationIndex(regname);
            if (i >= 0)
            {
                nanis[i].Pause = true;
            }
        }
        public bool GetAnimationPaused(string regname)
        {
            int i = getAnimationIndex(regname);
            if (i >= 0)
            {
                return  nanis[i].Pause ;
            }
            return false;
        }

        public int GetAnimationPlayedTimes(string index)
        {
            return GetAnimationPlayedTimes(getAnimationIndex(index));
        }
        public int GetAnimationPlayedTimes(int index)
        {
            if (index < 0)
            {
                return index;
            }
            return nanis[index].PlayedTimes;
        }

        int getAnimationIndex(string name)
        {
            for (int i = 0; i < nanis.Count; i++)
            {
                if (nanis[i].Name == name)
                {
                    return i;
                }
            }
            return -1;
        }
        void animationHeartbeat()
        {
            while (true)
            {
                for (int i = 0; i < nanis.Count; i++)
                {
                    try
                    {
                        double timespan = game.RunningTotalSeconds - nanis[i].LastVisitTime;
                        if (timespan * 1000 >= nanis[i].CurrentFrameDelay)
                        {
                            nanis[i].LastVisitTime = game.RunningTotalSeconds;
                            nanis[i].NextFrame(game.RunningTotalSeconds);
                        }
                    }
                    catch
                    {
                        break;
                    }
                }
                Thread.Sleep(1);
            }
        }
        public void LoadAnimation(string fileName, Vector3 from, Vector3 to, int delay)
        {
            LoadAnimation(fileName, (NAnimation)Util.LoadObject(fileName), from, to,delay);
        }
        public void LoadAnimation(string regName, string fileName, Vector3 from, Vector3 to, int delay)
        {
            LoadAnimation(regName, (NAnimation)Util.LoadObject(fileName), from, to,delay);
        }
        public void LoadAnimation(string regName, NAnimation nani, Vector3 from, Vector3 to,int delay)
        {
            if (nani == null)
            {
                return;
            }
            nani.Name = regName;
            nani.FlyTime = delay;
            nani.Reset();
            nani.LocationFrom = from;
            nani.LocationTo = to;
            nani.FirstVisitTime = nani.LastVisitTime = game.RunningTotalSeconds;
            nani.PlayedTimes = 0;
            nanis.Add(nani);
        }
        public void UnloadAnimation(string ani_name)
        {
            int i = getAnimationIndex(ani_name);
            if (i < 0)
            {
                return;
            }
            UnloadAnimation(i);
        }
        public void UnloadAnimation(int i)
        {
            nanis.RemoveAt(i);
        }
        public void DrawAnimation(string ani_name, bool isflip)
        {
            int i = getAnimationIndex(ani_name);
            if (i < 0)
            {
                return;
            }
            DrawAnimation(i,isflip);
        }
        public void DrawAnimation(int aniindex, bool isflip)
        {
            DrawImage(nanis[aniindex].CurrentFrame, nanis[aniindex].GetLocationNow(game.RunningTotalSeconds),isflip);
        }

        #endregion*/
        #endregion

        #region slow

        public void DrawImage(string fileName, Vector3 v3)
        {
            DrawImage(fileName, Color.White, v3);
        }
        public void DrawImage(string fileName, Color filterColor, Vector3 v3)
        {
            Image img;
            try
            {
                img = Image.FromFile(fileName);
            }
            catch{
                return;
            }
            DrawImage(img, filterColor, new Rectangle(new Point(), img.Size), v3);
        }
        public void DrawImage(string fileName, Color filterColor, Rectangle rect, Vector3 v3)
        {
            Image img;
            try
            {
                img = Image.FromFile(fileName);
            }
            catch
            {
                return;
            }
            DrawImage(img, filterColor, rect, v3);
        }
        public void DrawImage(Image img, Vector3 v3)
        {
            DrawImage(img, Color.White, v3);
        }
        public void DrawImage(Image img, Color filterColor, Vector3 v3)
        {
            DrawImage(img, filterColor, new Rectangle(new Point(), img.Size), v3);
        }
        public void DrawImage(Image img, Color filterColor,Rectangle rect, Vector3 v3)
        {
            if (game.Option.DrawMode == DrawMode.GPU)
            {
                using (Texture texture = new Texture(d3ddev, img.Width, img.Height, 1, Usage.None, Format.A8R8G8B8, Pool.Managed))
                {
                    using (Graphics g = texture.GetSurfaceLevel(0).GetGraphics())
                    {
                        //g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half;
                        //g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
                        g.DrawImage(img, new Point());
                    }
                    drawImageGPU(texture, img.Size, false, filterColor, rect, rect.Size, v3);
                }
            }
            else if (game.Option.DrawMode == DrawMode.CPU)
            {
                drawImageCPU(img, rect, Util.Vector32Point(v3), rect.Size);
            }
        }
        #endregion

        //public void DrawKImage(KImage img, Color filterColor, Vector3 v3)
        //{
        //    if (img.Texture == null)
        //    {
        //        img.Texture = KImage2Texture(img);
        //    }
        //    Vector3 v33 = Util.Vector3SubVector3(Util.Point2Vector3(img.DrawRectangle.Location), Util.Point2Vector3(img.OPoint));
        //    if (img.IsHorizontalFlip)
        //    {
        //        v33.X = -v33.X;
        //        v33.X -= img.DrawRectangle.Width;
        //    }

        //    v3 = Util.Vector3AddVector3(v3, v33);
        //    Rectangle rect = new Rectangle(new Point(), img.DrawRectangle.Size);
        //    drawTexture(img.Texture, img.IsHorizontalFlip, filterColor, img.DrawRectangle.Size, rect, img.DrawRectangle.Size, v3);
        //}

        //public void DrawKMovie(KMovie mov, Color filterColor, Vector3 v3)
        //{
        //    double now = game.Devices.Timer.TotalSeconds;
        //    double ts = now - mov.LastUpdateTime;
        //    if (ts > mov.CurrentFrame.Length)
        //    {
        //        mov.LastUpdateTime = now;
        //        mov.FrameIncrease();
        //    }
        //    DrawKImage(mov.CurrentFrame.KImage, filterColor, v3);
        //}
    }
}
